package com.soriya.nestlive.viewmodel

import android.app.Application
import android.content.Context
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.soriya.nestlive.application.MyApplication
import com.soriya.nestlive.constant.CommonConstant
import com.soriya.nestlive.db.AppDataBase
import com.soriya.nestlive.db.dao.ChannelInfoDao
import com.soriya.nestlive.db.dao.UserInfoDao
import com.soriya.nestlive.db.entity.UserInfoEntity
import com.soriya.nestlive.model.Channel
import com.soriya.nestlive.model.ResponseResult
import com.soriya.nestlive.model.User
import com.soriya.nestlive.repository.UserRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class UserModel @Inject constructor(
    private val userRepository: UserRepository,
    private val userInfoDao: UserInfoDao,
    private val channelInfoDao: ChannelInfoDao,
    application: Application
) : AndroidViewModel(application) {

    private val _userInfo = MutableStateFlow<UserInfoEntity?>(null)

    val userInfo: StateFlow<UserInfoEntity?> = _userInfo

    fun login(account: String, password: String): Flow<String> = flow {
        userRepository.login(account, password).collect { res ->
            when (res) {
                is ResponseResult.Success<*> -> {
                    if (res.code == 200) {
                        val token = res.data as String
                        emit(token)
                        return@collect
                    }
                    throw RuntimeException(res.message)
                }
                is ResponseResult.Failed -> {}
                is ResponseResult.Loading -> {}
            }
        }
    }

    fun logout() = flow<Unit?> {
        val edit = getApplication<MyApplication>().getSharedPreferences(
            CommonConstant.USER_INFO_KEY,
            Context.MODE_PRIVATE
        ).edit()

        edit.remove("token")
        edit.apply()

        userInfoDao.clear()
        channelInfoDao.clear()

        emit(Unit)
    }.flowOn(Dispatchers.IO)

    fun info() {
        viewModelScope.launch {
            val userInfo = userInfoDao.selectOne().first()

            if (userInfo != null && userInfo.updateTime > System.currentTimeMillis() - 1000 * 60 * 30) {
                _userInfo.emit(userInfo)
                return@launch
            }
            userRepository.info().collect { res ->
                when (res) {
                    is ResponseResult.Success<*> -> {
                        val user = res.data as User
                        val userInfoEntity = UserInfoEntity(
                            1,
                            user.id,
                            user.account,
                            user.nickname,
                            user.avatar,
                            user.description,
                            user.gender,
                            user.birth.time,
                            System.currentTimeMillis()
                        )
                        viewModelScope.launch(Dispatchers.IO) {
                            userInfoDao.insert(userInfoEntity)
                        }
                        _userInfo.emit(userInfoEntity)
                    }
                    is ResponseResult.Failed -> {}
                    is ResponseResult.Loading -> {}
                }
            }
        }
    }

}